package org.jdna.minecraft.tools;

import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileFilter;
import java.sql.Date;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingWorker;
import javax.swing.border.EmptyBorder;
import javax.swing.table.DefaultTableModel;

import org.apache.commons.io.FileUtils;
import org.apache.log4j.Logger;

public class RestoreDialog extends JDialog {
	private Logger log = Logger.getLogger(this.getClass());
	
	private final JPanel contentPanel = new JPanel();
	private JTable table;
	private JCheckBox chckbxRemoveCurrentMinecraft;
	private Preferences prefs;
	private JProgressBar progressBar;
	private JButton okButton;
	private JButton cancelButton;
	private JCheckBox chckbxRestoreMinecraftjarOnly;
	
	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		try {
			RestoreDialog dialog = new RestoreDialog();
			dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
			dialog.setVisible(true);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * Create the dialog.
	 */
	public RestoreDialog() {
		prefs = Application.getInstance().getPreferences();
		
		setBounds(100, 100, 640, 480);
		getContentPane().setLayout(new BorderLayout());
		contentPanel.setBorder(new EmptyBorder(5, 5, 5, 5));
		getContentPane().add(contentPanel, BorderLayout.CENTER);
		GridBagLayout gbl_contentPanel = new GridBagLayout();
		gbl_contentPanel.columnWidths = new int[]{0, 0};
		gbl_contentPanel.rowHeights = new int[]{0, 0, 0, 0, 0, 0};
		gbl_contentPanel.columnWeights = new double[]{1.0, Double.MIN_VALUE};
		gbl_contentPanel.rowWeights = new double[]{0.0, 0.0, 0.0, 0.0, 1.0, Double.MIN_VALUE};
		contentPanel.setLayout(gbl_contentPanel);
		{
			JLabel lblSelectABackup = new JLabel("Select a Backup from the list and click Restore");
			GridBagConstraints gbc_lblSelectABackup = new GridBagConstraints();
			gbc_lblSelectABackup.insets = new Insets(0, 0, 5, 0);
			gbc_lblSelectABackup.gridx = 0;
			gbc_lblSelectABackup.gridy = 0;
			contentPanel.add(lblSelectABackup, gbc_lblSelectABackup);
		}
		{
			chckbxRemoveCurrentMinecraft = new JCheckBox("Remove Current Minecraft Files");
			GridBagConstraints gbc_chckbxRemoveCurrentMinecraft = new GridBagConstraints();
			gbc_chckbxRemoveCurrentMinecraft.insets = new Insets(0, 0, 5, 0);
			gbc_chckbxRemoveCurrentMinecraft.gridx = 0;
			gbc_chckbxRemoveCurrentMinecraft.gridy = 1;
			contentPanel.add(chckbxRemoveCurrentMinecraft, gbc_chckbxRemoveCurrentMinecraft);
			
			// hiding this for now
			chckbxRemoveCurrentMinecraft.setVisible(false);
		}
		{
			chckbxRestoreMinecraftjarOnly = new JCheckBox("Restore minecraft.jar ONLY");
			chckbxRestoreMinecraftjarOnly.setSelected(true);
			GridBagConstraints gbc_chckbxRestoreMinecraftjarOnly = new GridBagConstraints();
			gbc_chckbxRestoreMinecraftjarOnly.insets = new Insets(0, 0, 5, 0);
			gbc_chckbxRestoreMinecraftjarOnly.gridx = 0;
			gbc_chckbxRestoreMinecraftjarOnly.gridy = 2;
			contentPanel.add(chckbxRestoreMinecraftjarOnly, gbc_chckbxRestoreMinecraftjarOnly);
		}
		{
			progressBar = new JProgressBar();
			GridBagConstraints gbc_progressBar = new GridBagConstraints();
			gbc_progressBar.fill = GridBagConstraints.HORIZONTAL;
			gbc_progressBar.insets = new Insets(0, 0, 5, 0);
			gbc_progressBar.gridx = 0;
			gbc_progressBar.gridy = 3;
			contentPanel.add(progressBar, gbc_progressBar);
		}
		{
			JScrollPane scrollPane = new JScrollPane();
			GridBagConstraints gbc_scrollPane = new GridBagConstraints();
			gbc_scrollPane.fill = GridBagConstraints.BOTH;
			gbc_scrollPane.gridx = 0;
			gbc_scrollPane.gridy = 4;
			contentPanel.add(scrollPane, gbc_scrollPane);
			{
				table = new JTable();
				DefaultTableModel model = new DefaultTableModel(new String[] { "Filename", "Date", "Size", "File"}, 0);
				List files = new ArrayList(FileUtils.listFiles(prefs.getBackupDir(), new String[] {"zip"}, false));
				Collections.sort(files, new Comparator() {
					@Override
					public int compare(Object o1, Object o2) {
						File f1 = (File) o1, f2 = (File) o2;
						Date d1 = new Date(f1.lastModified()), d2 = new Date(f2.lastModified());
						return d1.compareTo(d2) * -1;
					}
				});
				
				for (Object file: files) {
					File f = (File) file;
					model.addRow(new Object[] {f.getName(), f.lastModified(), new Double(((double)f.length())/1024d/1024d), f});
					System.out.println("ADDING: " + f);
				}
				table.setModel(model);
				table.getColumnModel().getColumn(0).setPreferredWidth(280);
				table.getColumnModel().getColumn(1).setCellRenderer(FormatRenderer.getDateTimeRenderer());
				table.getColumnModel().getColumn(1).setPreferredWidth(120);
				table.removeColumn(table.getColumnModel().getColumn(3));
				FormatRenderer renderer = FormatRenderer.getSizeMBRender();
				renderer.setHorizontalAlignment(JLabel.RIGHT);
				table.getColumnModel().getColumn(2).setCellRenderer(renderer);
				
				scrollPane.setViewportView(table);
			}
		}
		{
			JPanel buttonPane = new JPanel();
			buttonPane.setLayout(new FlowLayout(FlowLayout.RIGHT));
			getContentPane().add(buttonPane, BorderLayout.SOUTH);
			{
				okButton = new JButton("Restore");
				okButton.addActionListener(new ActionListener() {
					public void actionPerformed(ActionEvent e) {
						restore();
					}
				});
				okButton.setActionCommand("OK");
				buttonPane.add(okButton);
				getRootPane().setDefaultButton(okButton);
			}
			{
				cancelButton = new JButton("Cancel");
				cancelButton.addActionListener(new ActionListener() {
					public void actionPerformed(ActionEvent e) {
						setVisible(false);
					}
				});
				cancelButton.setActionCommand("Cancel");
				buttonPane.add(cancelButton);
			}
		}
	}

	protected void restore() {
		if (table.getSelectedRow()<0) {
			JOptionPane.showMessageDialog(this,
					"Select backup from the list", "Restore Message",
					JOptionPane.WARNING_MESSAGE);
			return;
		}
		
		try {
			final File file = (File) table.getModel().getValueAt(table.getSelectedRow(), 3);
//			FileUtils.deleteDirectory(prefs.getMinecraftDirAsFile());
			
			progressBar.setIndeterminate(true);
			SwingWorker t = new SwingWorker<Void, Void>() {
				@Override
				protected Void doInBackground() throws Exception {
					try {
						okButton.setEnabled(false);
						if (chckbxRestoreMinecraftjarOnly.isSelected()) {
							Util.unzip(file, prefs.getMinecraftDirAsFile(), new FileFilter() {
								@Override
								public boolean accept(File pathname) {
									return pathname.getName().equalsIgnoreCase("minecraft.jar");
								}
							});
						} else {
							Util.unzip(file, prefs.getMinecraftDirAsFile());
						}
						JOptionPane.showMessageDialog(RestoreDialog.this,
								"Restored " + file, "Restore Message",
								JOptionPane.INFORMATION_MESSAGE);
					} catch (Throwable t) {
						log.warn("Failed to restore files ", t);
						JOptionPane.showMessageDialog(RestoreDialog.this,
								"Failed to restore files.  Message: " + t.getMessage(), "Restore Message",
								JOptionPane.WARNING_MESSAGE);
					} finally {
						progressBar.setIndeterminate(false);
						okButton.setEnabled(true);
					}
					return null;
				}
			};
			t.execute();
		} catch (Throwable t) {
			log.warn("Failed to restore files ", t);
			JOptionPane.showMessageDialog(this,
					"Failed to restore files.  Message: " + t.getMessage(), "Restore Message",
					JOptionPane.WARNING_MESSAGE);
		}
	}
}
